Flush writable pagetable state whenever a domain is
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 15 Oct 2005 16:19:43 +0000 (17:19 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 15 Oct 2005 16:19:43 +0000 (17:19 +0100)
synchronously paused (by Xen or by domain0), or when
it shuts down.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/mm.c
xen/common/domain.c
xen/include/asm-x86/mm.h

index 8fcb246906bc3c0e580890c37c87e2f090d7d763..3554c011cf10417efcb6108010694cebece7e7f9 100644 (file)
@@ -1755,7 +1755,7 @@ int do_mmuext_op(
             goto pin_page;
 
         case MMUEXT_UNPIN_TABLE:
-            if ( unlikely(!(okay = get_page_from_pagenr(mfn, FOREIGNDOM))) )
+            if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) )
             {
                 MEM_LOG("Mfn %lx bad domain (dom=%p)",
                         mfn, page_get_owner(page));
@@ -2908,6 +2908,7 @@ int revalidate_l1(
 {
     l1_pgentry_t ol1e, nl1e;
     int modified = 0, i;
+    struct vcpu *v;
 
     for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
     {
@@ -2940,7 +2941,11 @@ int revalidate_l1(
              */
             memcpy(&l1page[i], &snapshot[i],
                    (L1_PAGETABLE_ENTRIES - i) * sizeof(l1_pgentry_t));
-            domain_crash();
+
+            /* Crash the offending domain. */
+            set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+            for_each_vcpu ( d, v )
+                vcpu_sleep_nosync(v);
             break;
         }
         
@@ -3019,8 +3024,8 @@ void ptwr_flush(struct domain *d, const int which)
     modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
     unmap_domain_page(pl1e);
     perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
-    ptwr_eip_stat_update(  d->arch.ptwr[which].eip, d->domain_id, modified);
-    d->arch.ptwr[which].prev_nr_updates  = modified;
+    ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
+    d->arch.ptwr[which].prev_nr_updates = modified;
 
     /*
      * STEP 3. Reattach the L1 p.t. page into the current address space.
@@ -3369,7 +3374,9 @@ int ptwr_init(struct domain *d)
 
 void ptwr_destroy(struct domain *d)
 {
+    LOCK_BIGLOCK(d);
     cleanup_writable_pagetable(d);
+    UNLOCK_BIGLOCK(d);
     free_xenheap_page(d->arch.ptwr[PTWR_PT_ACTIVE].page);
     free_xenheap_page(d->arch.ptwr[PTWR_PT_INACTIVE].page);
 }
index 96c3b0a083c8e6625ce6e58f6b6b1dafe4e620c7..7a50d0e74beca4fa00afe94d29676e1dcd263a9b 100644 (file)
@@ -290,6 +290,8 @@ void domain_pause(struct domain *d)
         atomic_inc(&v->pausecnt);
         vcpu_sleep_sync(v);
     }
+
+    sync_pagetable_state(d);
 }
 
 void vcpu_unpause(struct vcpu *v)
@@ -318,6 +320,8 @@ void domain_pause_by_systemcontroller(struct domain *d)
         for_each_vcpu ( d, v )
             vcpu_sleep_sync(v);
     }
+
+    sync_pagetable_state(d);
 }
 
 void domain_unpause_by_systemcontroller(struct domain *d)
index 9b79f86d6f4a76cd22632be79b1a6f325963a2e8..a13346c25b7f9e71990cdf882059a669ee905d0c 100644 (file)
@@ -336,7 +336,12 @@ int  ptwr_do_page_fault(struct domain *, unsigned long,
 int  revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *);
 
 void cleanup_writable_pagetable(struct domain *d);
-#define sync_pagetable_state(d) cleanup_writable_pagetable(d)
+#define sync_pagetable_state(d)                 \
+    do {                                        \
+        LOCK_BIGLOCK(d);                        \
+        cleanup_writable_pagetable(d);          \
+        UNLOCK_BIGLOCK(d);                      \
+    } while ( 0 )
 
 int audit_adjust_pgtables(struct domain *d, int dir, int noisy);